package com.geline.mybatisplus.handler;

import cn.hutool.core.util.StrUtil;
import com.geline.mybatisplus.annotation.ExtractValue;
import com.geline.mybatisplus.util.SpELParserUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @ExtractValue 处理器
 *
 * @author mx
 * @date 2025/9/23
 */
@Slf4j
public class ExtractValueHandler {

    public void handle(Object entity) {
        List<ExtractValueResult> list = new ArrayList<>();
        Field[] fields = entity.getClass().getDeclaredFields();
        for(Field field : fields){
            ExtractValue[] values = field.getAnnotationsByType(ExtractValue.class);
            if(values != null && values.length>0){
                for(ExtractValue extractValue : values){
                    String cond = extractValue.condition();
                    if(StrUtil.isNotBlank(cond)){
                        Boolean execute = SpELParserUtil.executeBoolean(entity, cond);
                        if(execute){
                            Object value = SpELParserUtil.executeValue(entity, extractValue.value(), field.getType());
                            ExtractValueResult result = new ExtractValueResult(field.getName(), value, extractValue.order());
                            list.add(result);
                            break;
                        }
                    }
                }
            }
        }
        BeanWrapper wrapper = new BeanWrapperImpl(entity);
        //排序：从小到大执行
        list.stream().sorted(Comparator.comparingInt(ExtractValueResult::getOrder));
        Map<String, Object> updateValue = new HashMap<>();
        for(ExtractValueResult result : list){
            String fieldName = result.getFieldName();
            Object defValue = result.getValue();
            //支持字符串转Integer,Long,Float,Double,BigDecimal,Date
            wrapper.setPropertyValue(fieldName, defValue);
            updateValue.put(fieldName, defValue);
        }
        if(updateValue.size()>0){
            log.info(">>>> updateFieldValue[{}]={}", entity.getClass().getSimpleName(), updateValue);
        }
    }

    @Getter
    @Setter
    @AllArgsConstructor
    class ExtractValueResult{
        private String fieldName;
        private Object value;
        private int order;
    }
}
